package com.pantech.imnak0.translationhelper.launcher;

import java.awt.BorderLayout;
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.File;
import java.io.IOException;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;

import com.pantech.imnak0.translationhelper.XLSCreator;
import com.pantech.imnak0.translationhelper.XLSParser;
import com.pantech.imnak0.translationhelper.XMLCreator;
import com.pantech.imnak0.translationhelper.XMLParser;
import com.pantech.imnak0.translationhelper.XMLSort;
import com.pantech.imnak0.utility.FileUtility;

/**
 * XML <-> 번역 요청용 excel file 을 실행하기 위한 프로젝트의 GUI 를 담당하는 class이다.
 * Swing 을 이용하여 GUI 를 제공한다.
 * 
 * @author Nakyung Lim, ES Team #1
 *
 */
public class GUILauncher {
	private static final String VERSION = "1.1.1";
	private static final String USER_MANUAL = "/TranslationHelper_Manual.pdf";

	private JFrame frame;
	private JPanel panel;
	private JMenuBar menuBar;

	private File previousFolder;
	private File openFile = null;
	private File savePath = null;

	public void go() {
		frame = new JFrame();
		panel = new JPanel();
		menuBar = new JMenuBar();

		// Buttons
		JButton button1 = new JButton("번역 요청 (XML => Excel)");
		button1.addActionListener(XmlToExcelListener);

		JButton button2 = new JButton("번역 완료 (Excel => XML)");
		button2.addActionListener(ExcelToXmlListener);

		JButton button3 = new JButton("XML 스트링 순서 정렬");
		button3.addActionListener(sortListener);

		// Menu
		initializeMenuBar();

		// Panel
		panel.add(button1);
		panel.add(button2);
		panel.add(button3);

		// Frame
		frame.setTitle("Translation Helper");
		frame.setJMenuBar(menuBar);
		frame.getContentPane().add(BorderLayout.CENTER, panel);
		frame.setSize(300, 200);
		frame.addWindowListener(new WindowListener() {
			@Override
			public void windowOpened(WindowEvent arg0) {
			}

			@Override
			public void windowIconified(WindowEvent arg0) {
			}

			@Override
			public void windowDeiconified(WindowEvent arg0) {
			}

			@Override
			public void windowDeactivated(WindowEvent arg0) {
			}

			@Override
			public void windowClosing(WindowEvent arg0) {
				System.exit(0);
			}

			@Override
			public void windowClosed(WindowEvent arg0) {
			}

			@Override
			public void windowActivated(WindowEvent arg0) {
			}
		});
		frame.setVisible(true);
	}

	/**
	 * Menu bar 생성
	 */
	private void initializeMenuBar() {
		// File menu
		JMenu menu1 = new JMenu("File");
		menuBar.add(menu1);

		// menu items
		JMenuItem fileMenuItem1 = new JMenuItem("번역 요청 (XML => Excel)");
		JMenuItem fileMenuItem2 = new JMenuItem("번역 완료 (Excel => XML)");
		JMenuItem fileMenuItem3 = new JMenuItem("XML 스트링 순서 정렬");

		fileMenuItem1.addActionListener(XmlToExcelListener);
		fileMenuItem2.addActionListener(ExcelToXmlListener);
		fileMenuItem3.addActionListener(sortListener);

		menu1.add(fileMenuItem1);
		menu1.add(fileMenuItem2);
		menu1.add(fileMenuItem3);

		// Help menu
		JMenu menu2 = new JMenu("Help");
		menuBar.add(menu2);

		// menu items
		JMenuItem helpMenuItem1 = new JMenuItem("About");
		JMenuItem helpMenuItem2 = new JMenuItem("Manual");

		helpMenuItem1.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent event) {
				JOptionPane
						.showMessageDialog(
								frame,
								"Translation Helper ver."
										+ VERSION
										+ "\n\nstrings.xml 을 번역 요청용 excel 파일로,\n번역 완료된 excel 파일을 xml로 자동 변환해 주는 어플입니다.\n\nES Team #1, Nakyung Lim\nlim.nakyung@pantech.com");
			}
		});
		helpMenuItem2.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent event) {
				try {
					Desktop.getDesktop().open(FileUtility.createFileFromResource(getClass(), USER_MANUAL));
				} catch (Exception e) {
				}
			}
		});

		menu2.add(helpMenuItem1);
		menu2.add(helpMenuItem2);
	}

	/**
	 * XML 을 Excel 로 변환하는 버튼의 Listener
	 */
	private ActionListener XmlToExcelListener = new ActionListener() {
		@Override
		public void actionPerformed(ActionEvent event) {
			FileFilter filter = new FileNameExtensionFilter("XML files", "xml");
			String fileOpenMessage = "번역 요청할 xml 파일을 선택하세요";
			String fileSaveMessage = "변환된 엑셀을 저장할 폴더를 선택하세요";

			boolean ret = openDialogs(filter, fileOpenMessage, fileSaveMessage);

			if (ret) {
				XMLParser xmlParser = new XMLParser(openFile);
				xmlParser.parse();

				XLSCreator xlsCreator = new XLSCreator(savePath, xmlParser.getHashmapList());
				xlsCreator.create();

				try {
					Desktop.getDesktop().open(savePath);
					Desktop.getDesktop().open(new File(savePath.getAbsolutePath() + XLSCreator.SAVEFILE_NAME));
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	};

	/**
	 * Excel 을 XML로 변환하는 버튼의 Listener
	 */
	private ActionListener ExcelToXmlListener = new ActionListener() {
		@Override
		public void actionPerformed(ActionEvent event) {
			FileFilter filter = new FileNameExtensionFilter("Excel files", new String[] { "xls", "xlsx" });
			String fileOpenMessage = "엑셀로 변환할 xml 파일을 선택하세요";
			String fileSaveMessage = "변환된 xml을 저장할 폴더를 선택하세요";

			boolean ret = openDialogs(filter, fileOpenMessage, fileSaveMessage);

			if (ret) {
				XLSParser xlsParser = new XLSParser(openFile);
				xlsParser.parse();

				XMLCreator xmlCreator = new XMLCreator(savePath, xlsParser.getHashmapList());
				xmlCreator.create();

				try {
					Desktop.getDesktop().open(savePath);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	};

	/**
	 * 기존의 XML과 동일한 스트링 순서로 신규 생성된 XML의 순서를 변경한다.
	 */
	private ActionListener sortListener = new ActionListener() {
		@Override
		public void actionPerformed(ActionEvent event) {
			FileFilter filter = new FileNameExtensionFilter("XML files", "xml");
			String criteriaSelectMessage = "스트링 순서의 기준이 될 xml을 선택하세요";
			String targetSelectMesasge = "스트링 순서를 변경할 xml을 선택하세요";

			boolean ret = openDialogsForXML(filter, criteriaSelectMessage, targetSelectMesasge);

			if (ret) {
				XMLSort sorter = new XMLSort(openFile, savePath);
				sorter.parseAndSort();

				try {
					XMLCreator xmlCreator = new XMLCreator(savePath, sorter.getSortedHashMap());
					xmlCreator.createSorted();
					Desktop.getDesktop().open(savePath);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	};

	/**
	 * Open 할 file과 Save할 폴더를 선택하는 Dialog를 차례로 호출한다.
	 * 
	 * @return true if both Open and Save file successfully selected, false if not
	 */
	private boolean openDialogs(FileFilter filter, String fileOpenMessage, String fileSaveMessage) {
		openFile = fileOpenDialog(filter, fileOpenMessage);
		if (openFile == null)
			return false;

		savePath = fileSaveDialog(filter, fileSaveMessage);
		if (savePath == null)
			return false;

		return true;
	}

	/**
	 * 기준이 될 xml과 순서를 정렬할 xml을 선택하는 Dialog를 차례로 호출한다.
	 */
	private boolean openDialogsForXML(FileFilter filter, String fileOpenMessage, String fileSaveMessage) {
		openFile = fileOpenDialog(filter, fileOpenMessage);
		if (openFile == null)
			return false;

		savePath = fileOpenDialog(filter, fileSaveMessage);
		if (savePath == null)
			return false;

		return true;
	}

	/**
	 * Open 할 파일을 선택하는 다이얼로그를 생성한다.
	 * @param filter
	 * @param fileOpenMessage
	 * @return
	 */
	private File fileOpenDialog(FileFilter filter, String fileOpenMessage) {
		// Open Dialog
		JFileChooser fileOpen = new JFileChooser(previousFolder);
		fileOpen.setDialogTitle(fileOpenMessage);
		fileOpen.addChoosableFileFilter(filter);
		int openRet = fileOpen.showDialog(panel, "Open");

		// Get the selected file
		if (openRet == JFileChooser.APPROVE_OPTION) {
			File file = fileOpen.getSelectedFile();
			previousFolder = new File(file.getAbsolutePath());

			return file;
		} else {
			return null;
		}
	}

	/**
	 * Save 할 파일을 선택하는 다이얼로그를 생성한다.
	 * @param filter
	 * @param fileSaveMessage
	 * @return
	 */
	private File fileSaveDialog(FileFilter filter, String fileSaveMessage) {
		// Select the output folder
		JFileChooser fileSave = new JFileChooser(previousFolder) {
			private static final long serialVersionUID = 1L;

			@Override
			public void approveSelection() {
				if (getSelectedFile().isDirectory())
					super.approveSelection();
				else
					return;
			}
		};
		fileSave.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		fileSave.setDialogTitle(fileSaveMessage);
		int saveRet = fileSave.showDialog(panel, "Save");

		// Get the selected file or directory
		if (saveRet == JFileChooser.APPROVE_OPTION) {
			File file = fileSave.getSelectedFile();
			previousFolder = new File(file.getAbsolutePath());

			return file;
		} else {
			return null;
		}
	}
}